package OpenToday.GUI;

import OpenToday.Configuration.OpenTodayConfiguration;
import OpenToday.IManager;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.lcdui.*;
/*
 * MainGUI.java
 *
 * Created on 5 ������ 2007, 08:36
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 *
 *Note: This source code is protected under the This software is licensed under the CC-GNU GPL.
 */

/**
 *
 * @author Menny Even Danan (c) 2007. Note: This source code is protected under the This software is licensed under the CC-GNU GPL.
 */
public class MainCanvas extends Canvas implements IOpenTodayGUI
{
    private class RowData
    {
        public final String Text;
	public RowData(String text)
	{
	    Text = text;
	}
    }
    private class DayRow extends RowData
    {
	public DayRow(String dayTitle)
	{
	    super(dayTitle);
	}
    }
    
    private class EventRow extends RowData
    {
        public final boolean AllDayEvent;
	public EventRow(String eventTitle, boolean allDayEvent)
	{
	    super(eventTitle);
            AllDayEvent = allDayEvent;
	}
    }
    
     private class TodoRow extends RowData
    {
         public final boolean OverDue;
	 public final boolean Completed;
	 public TodoRow(String eventTitle, boolean overDue, boolean completed)
	{
	    super(eventTitle);
            OverDue = overDue;
	    Completed = completed;
	}
    }
    
    private final Image IMAGE_EVENT;
    private final Image IMAGE_NEED_TODO;
    private final Image IMAGE_HAVE_DONE_TODO;
    private final Image IMAGE_FORGOT_TODO;
    private Image IMAGE_EMPTY;
    private Font dayFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_SMALL);
    private Font eventFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_SMALL);
    
    private int m_firstLineOffset;
    //these three must me remembered so, i'll know when to rebuild the placeholder
    private int[] m_BackgroundRGB = new int[]{255, 255, 255};
    private final IManager m_manager;
    private final Vector m_GUIrows;
    //private final Vector m_beforeGUIrows;
    
    /** Creates a new instance of MainCanvas */
    public MainCanvas(IManager manager) throws IOException
    {
	m_manager = manager;
        IMAGE_EVENT = Image.createImage("/Event.PNG");
        IMAGE_NEED_TODO = Image.createImage("/NeedToDo.PNG");
        IMAGE_HAVE_DONE_TODO = Image.createImage("/HaveDoneToDo.PNG");
        IMAGE_FORGOT_TODO = Image.createImage("/ForgotToDo.PNG");
	super.setTitle(null);
	m_firstLineOffset = 0;
	m_GUIrows = new Vector();
	//m_beforeGUIrows = new Vector();
        FillPlaceholder();
    }

    public void RepaintRequired()
    {
	super.repaint();
    }
    
    protected void paint(Graphics g)
    {
	OpenTodayConfiguration cnf = OpenTodayConfiguration.getInstance();
	int y = cnf.get_ScreenTopOffset();
	SetBackgroundColor();
	g.setColor(m_BackgroundRGB[0], m_BackgroundRGB[1], m_BackgroundRGB[2]);
	g.fillRect (0, 0, getWidth(), getHeight());
	
	Image bgImage = cnf.GetLoadedBackgroundImage();
	System.out.println("Drawing image?" + (bgImage != null));
	if (bgImage != null)
	{
	    g.drawImage(bgImage, 0, 0, Graphics.LEFT | Graphics.TOP);
	}
	
	int[] dayRGB = cnf.get_DayTextRGB();
	int[] eventRGB = cnf.get_EventTextRGB();
	
//	System.out.println("Listing overdue. Rows:" + m_beforeGUIrows.size());
//	for (int rowIndex = 0; rowIndex < m_beforeGUIrows.size(); rowIndex++) 
//	{
//	    RowData oRow = (RowData)m_beforeGUIrows.elementAt(rowIndex);
//	    y = DrawRow(g, y, oRow, dayRGB, eventRGB);
//	}
	
        dayFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, cnf.getTitleFontSize());
        eventFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, cnf.getEventFontSize());
    
	System.out.println("Listing events. Rows:" + m_GUIrows.size());
	for (int rowIndex = 0; rowIndex < m_GUIrows.size(); rowIndex++) 
	{
	    RowData oRow = (RowData)m_GUIrows.elementAt(rowIndex);
	    y = DrawRow(g, y, oRow, dayRGB, eventRGB);
	}
    }

    public void Clear()
    {
	m_GUIrows.removeAllElements();
	//m_beforeGUIrows.removeAllElements();
    }

    public void SetFirstLineOffset(int offset)
    {
	m_firstLineOffset = offset;
    }

    public void AddDayLine(String dayString)
    {
	m_GUIrows.addElement(new DayRow(dayString));
    }

    private void InternalAddEventLine(String eventString, boolean allDayEvent)
    {
	m_GUIrows.addElement(new EventRow(eventString, allDayEvent));
    }
    
    private String ConvertToCharValue(String value)
    {
	try
	{
	    String newValue="";
	    for(int i=0; i<value.getBytes("UNICODE").length;i++)
		newValue += ((int)value.charAt(i));

	    return newValue;
	}
	catch(Exception e)
	{
	    return value;
	}
    }
    
    public void AddLine(String text)
    {
	text = RTLFix(text);
        m_GUIrows.addElement(new RowData(text));
    }

    public void AddEventLine(boolean currentEvent, String eventTime, String eventString)
    {
	eventString = RTLFix(eventString);
	InternalAddEventLine((currentEvent? ">":"") + eventTime + "-" + eventString, false);
    }

    public void AddAllDayEventLine(String eventString)
    {
	eventString = RTLFix(eventString);
	InternalAddEventLine(eventString, true);
    }

    public void AddToDoLine(boolean overdue, boolean completed, String todoString)
    {
	todoString = RTLFix(todoString);
//	if (overdue)
//	{
//	    if (m_beforeGUIrows.size() == 0)
//		m_beforeGUIrows.addElement(new DayRow(OpenTodayConfiguration.getInstance().getOverdueItemsTitle()));
//	    m_beforeGUIrows.addElement(new TodoRow(todoString, overdue, completed));
//	}
//	else
	    m_GUIrows.addElement(new TodoRow(todoString, overdue, completed));
    }
    
    public Displayable getDisplayable()
    {
	return this;
    }    

    private static String RTLFix(String eventString)
    {
	System.out.println("RTLFix called:" + eventString);
	byte[] bytes;
	try
	{
	    bytes = eventString.getBytes("UTF8");
	    System.out.println("RTLFix UTF8");
	}
	catch(Exception ex)
	{
	    System.out.println("RTLFix other! "+ex.getMessage());
	    bytes = eventString.getBytes();
	}

/// Use this code to find new languages which are RTL. In UTF8 every extended character (i.e., Hebrew)
/// is stored in two bytes. Therefore, if the first byte of the two is (-41), then we are talking hebrew.
//	String newValue = "";
//	for(int i=0; i<bytes.length; i++)
//	{
//	    Byte b = new Byte(bytes[i]);
//	    newValue += (b.toString() + ",");
//	}
//	return newValue;
	
	for(int i=0; i<bytes.length; i+=2)//two chars jump
	{
	    System.out.println("RTLFix byte "+((int)bytes[i]));
	    
	    if ((bytes[i] == -41))//-41: Hebrew characters
	    {
		System.out.println("RTLFix REVERSING!");
		return ReverseString(eventString);
	    }
	}
	System.out.println("RTLFix NOT RTL");
	return eventString;
    }

    private static String ReverseString(String eventString)
    {
            System.out.println("ReverseString start "+eventString);
	    String reversed = "";
            for(int i=eventString.length()-1; i>=0; i--)
            {
                reversed += eventString.charAt(i);
            }
	    System.out.println("ReverseString end "+reversed);
            return reversed;
    }

    private void SetBackgroundColor() 
    {
	OpenTodayConfiguration cnf = OpenTodayConfiguration.getInstance();
	int[] RGB = cnf.get_BackgroundRGB();
	if ((m_BackgroundRGB[0] != RGB[0]) ||
	    (m_BackgroundRGB[1] != RGB[1]) ||
	    (m_BackgroundRGB[2] != RGB[2]))
	{
	    m_BackgroundRGB = RGB;
	    FillPlaceholder();
	}
    }
    
    private void FillPlaceholder()
    {
        int[] transperantEmptyEventPlaceholder = new int[16*16];
        for(int i=0; i< transperantEmptyEventPlaceholder.length; i++)
            transperantEmptyEventPlaceholder[i] = 0;
        
        IMAGE_EMPTY = Image.createRGBImage(transperantEmptyEventPlaceholder, 16, 16, true);
    }

    private int DrawRow(Graphics g, int y, RowData oRow, int[] dayRGB, int[] eventRGB) 
    {
	try
	{
	    //default behaviour
	    String text= oRow.Text;
	    Font font  = eventFont;
	    g.setColor(eventRGB[0], eventRGB[1], eventRGB[2]);
	    Image img = null;
	    //specific stuff
	    if (oRow instanceof DayRow)
	    {
		DayRow row = (DayRow)oRow;
		g.setColor(dayRGB[0], dayRGB[1], dayRGB[2]);
		font = dayFont;
		img = null;
	    }
	    else if (oRow instanceof EventRow)
	    {
		EventRow row = (EventRow)oRow;
		g.setColor(eventRGB[0], eventRGB[1], eventRGB[2]);
		font = eventFont;
		if (row.AllDayEvent)
		    img = IMAGE_EMPTY;
		else
		    img = IMAGE_EVENT;
	    }
	    else if (oRow instanceof TodoRow)
	    {
		TodoRow row = (TodoRow)oRow;
		g.setColor(eventRGB[0], eventRGB[1], eventRGB[2]);
		font = eventFont;
		if (row.OverDue)
		    img = IMAGE_FORGOT_TODO;
		else if (row.Completed)
		    img = IMAGE_HAVE_DONE_TODO;
		else
		    img = IMAGE_NEED_TODO;
	    }

	    int x = 1;
	    if (img != null)
	    {
		g.drawImage(img, x, y, Graphics.TOP | Graphics.LEFT);
		x += img.getWidth() + 1;
	    }
	    g.setFont(font);
	    g.drawString(text, x, y, Graphics.TOP | Graphics.LEFT);
	    y += font.getHeight () + 1;
	}
	catch(Exception e)
	{
	    System.err.println(e.getMessage());
	    e.printStackTrace();
	    m_manager.OnError("While painting the Today Screen:\n\r" + e.getMessage() + "\n\r" + e.toString()); 
	}
	return y;
    }
}
